<template>
  <div 
    :class="[
      'bx-tag-input',
      'bx-glass',
      {
        'bx-tag-input--disabled': disabled,
        'bx-tag-input--focused': focused || showDropdown,
        [`bx-tag-input--${size}`]: size
      }
    ]"
    @click="handleWrapperClick"
  >
    <div class="bx-tag-input__tags">
      <transition-group name="tag-list" tag="span">
        <span 
          v-for="(tag, index) in currentTags"
          :key="tag"
          class="bx-tag-input__tag bx-tag bx-glass"
        >
          {{ tag }}
          <BxIcon 
            v-if="!disabled && !readonly"
            name="x"
            class="bx-tag-input__tag-close"
            @click.stop="removeTag(index)"
          />
        </span>
      </transition-group>
      <input
        ref="inputRef"
        v-model="inputValue"
        type="text"
        :placeholder="currentTags.length === 0 ? placeholder : ''"
        :disabled="disabled"
        :readonly="readonly"
        class="bx-tag-input__input"
        @focus="handleFocus"
        @blur="handleBlur"
        @keydown.enter="addTag"
        @keydown.backspace="handleBackspace"
        @input="handleInput"
      />
    </div>

    <BxIcon 
      v-if="clearable && currentTags.length > 0 && !disabled && !readonly"
      name="x-circle"
      class="bx-tag-input__clear"
      @click.stop="handleClear"
    />

    <div 
      v-if="showDropdown && filteredOptions.length > 0"
      class="bx-tag-input__dropdown bx-glass"
    >
      <ul class="bx-tag-input__list">
        <li 
          v-for="(option, index) in filteredOptions"
          :key="index"
          :class="[
            'bx-tag-input__item',
            {
              'bx-tag-input__item--active': activeIndex === index
            }
          ]"
          @click="handleSelectOption(option)"
          @mouseenter="activeIndex = index"
        >
          {{ option }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { ref, computed, watch, nextTick } from 'vue'
import BxInput from './BxInput.vue'
import BxIcon from '../basic/BxIcon.vue'

export default {
  name: 'BxTagInput',
  components: {
    BxInput,
    BxIcon
  },
  props: {
    modelValue: {
      type: Array,
      default: () => []
    },
    placeholder: {
      type: String,
      default: '请输入标签'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: false
    },
    size: {
      type: String,
      default: 'medium',
      validator: (value) => ['small', 'medium', 'large'].includes(value)
    },
    options: {
      type: Array,
      default: () => []
    },
    max: {
      type: Number,
      default: Infinity
    },
    allowCreate: {
      type: Boolean,
      default: true
    }
  },
  emits: ['update:modelValue', 'change', 'focus', 'blur', 'clear', 'tag-add', 'tag-remove'],
  setup(props, { emit }) {
    const inputRef = ref(null)
    const inputValue = ref('')
    const currentTags = ref([...props.modelValue])
    const focused = ref(false)
    const showDropdown = ref(false)
    const activeIndex = ref(-1)

    const filteredOptions = computed(() => {
      if (!props.options.length || !inputValue.value) return []
      return props.options.filter(option => 
        String(option).toLowerCase().includes(inputValue.value.toLowerCase()) &&
        !currentTags.value.includes(option)
      )
    })

    watch(() => props.modelValue, (newVal) => {
      currentTags.value = [...newVal]
    }, { deep: true })

    const emitChange = () => {
      emit('update:modelValue', currentTags.value)
      emit('change', currentTags.value)
    }

    const addTag = () => {
      if (props.disabled || props.readonly) return
      
      const value = inputValue.value.trim()
      if (value && !currentTags.value.includes(value) && currentTags.value.length < props.max) {
        currentTags.value.push(value)
        inputValue.value = ''
        emitChange()
        emit('tag-add', value)
      }
      showDropdown.value = false
      activeIndex.value = -1
    }

    const removeTag = (index) => {
      if (props.disabled || props.readonly) return
      
      const removedTag = currentTags.value.splice(index, 1)[0]
      emitChange()
      emit('tag-remove', removedTag)
    }

    const handleBackspace = (event) => {
      if (inputValue.value === '' && currentTags.value.length > 0) {
        event.preventDefault()
        removeTag(currentTags.value.length - 1)
      }
    }

    const handleFocus = (event) => {
      focused.value = true
      showDropdown.value = true
      emit('focus', event)
    }

    const handleBlur = (event) => {
      focused.value = false
      // 延迟关闭，以便点击选项
      setTimeout(() => {
        showDropdown.value = false
        activeIndex.value = -1
        // 如果有输入但未添加为标签，则清空
        if (inputValue.value && !props.allowCreate) {
          inputValue.value = ''
        }
      }, 150)
      emit('blur', event)
    }

    const handleInput = (event) => {
      inputValue.value = event.target.value
      showDropdown.value = true
      activeIndex.value = -1
    }

    const handleSelectOption = (option) => {
      if (!currentTags.value.includes(option) && currentTags.value.length < props.max) {
        currentTags.value.push(option)
        inputValue.value = ''
        emitChange()
        emit('tag-add', option)
      }
      showDropdown.value = false
      activeIndex.value = -1
      inputRef.value?.focus()
    }

    const handleClear = () => {
      currentTags.value = []
      inputValue.value = ''
      emitChange()
      emit('clear')
    }

    const handleWrapperClick = () => {
      inputRef.value?.focus()
    }

    return {
      inputRef,
      inputValue,
      currentTags,
      focused,
      showDropdown,
      activeIndex,
      filteredOptions,
      addTag,
      removeTag,
      handleBackspace,
      handleFocus,
      handleBlur,
      handleInput,
      handleSelectOption,
      handleClear,
      handleWrapperClick
    }
  }
}
</script>

<style scoped>
.bx-tag-input {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  min-height: 36px;
  padding: 4px 8px;
  border: 1px solid var(--bx-glass-border);
  border-radius: var(--bx-radius-medium);
  background: var(--bx-glass-bg);
  backdrop-filter: var(--bx-glass-blur);
  transition: all var(--bx-transition-medium);
  font-family: var(--bx-font-family);
  cursor: text;
  position: relative;
}

.bx-tag-input:hover {
  border-color: var(--bx-glass-border-hover);
  background: var(--bx-glass-bg-hover);
}

.bx-tag-input--focused {
  border-color: rgba(0, 122, 255, 0.5);
  box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.1);
}

.bx-tag-input--disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.bx-tag-input--small {
  min-height: 32px;
  padding: 2px 6px;
}

.bx-tag-input--large {
  min-height: 40px;
  padding: 6px 10px;
}

.bx-tag-input__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1;
}

.bx-tag-input__tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: var(--bx-radius-small);
  background: rgba(0, 122, 255, 0.2);
  border: 1px solid rgba(0, 122, 255, 0.3);
  color: var(--bx-text-primary);
  font-size: 13px;
}

.bx-tag-input--small .bx-tag-input__tag {
  font-size: 12px;
  padding: 3px 6px;
}

.bx-tag-input--large .bx-tag-input__tag {
  font-size: 14px;
  padding: 5px 10px;
}

.bx-tag-input__tag-close {
  margin-left: 6px;
  cursor: pointer;
  font-size: 10px;
  color: var(--bx-text-secondary);
}

.bx-tag-input__tag-close:hover {
  color: var(--bx-text-primary);
}

.bx-tag-input__input {
  flex: 1;
  min-width: 80px;
  border: none;
  outline: none;
  background: transparent;
  color: var(--bx-text-primary);
  font-size: 14px;
  padding: 4px 0;
}

.bx-tag-input--small .bx-tag-input__input {
  font-size: 13px;
  padding: 3px 0;
}

.bx-tag-input--large .bx-tag-input__input {
  font-size: 15px;
  padding: 5px 0;
}

.bx-tag-input__input::placeholder {
  color: var(--bx-text-tertiary);
}

.bx-tag-input__clear {
  font-size: 14px;
  color: var(--bx-text-tertiary);
  cursor: pointer;
  margin-left: 8px;
}

.bx-tag-input__clear:hover {
  color: var(--bx-text-primary);
}

.bx-tag-input__dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 100%;
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid var(--bx-glass-border);
  border-radius: var(--bx-radius-medium);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  animation: bx-fade-in-up 0.2s ease-out;
}

.bx-tag-input__list {
  list-style: none;
  padding: 4px 0;
  margin: 0;
}

.bx-tag-input__item {
  padding: 8px 12px;
  cursor: pointer;
  color: var(--bx-text-primary);
  transition: background-color var(--bx-transition-fast);
}

.bx-tag-input__item:hover,
.bx-tag-input__item--active {
  background: var(--bx-glass-bg-hover);
}

.bx-tag-input__empty {
  padding: 16px;
  text-align: center;
  color: var(--bx-text-tertiary);
}

/* Tag transition */
.tag-list-enter-active, .tag-list-leave-active {
  transition: all 0.3s ease;
}
.tag-list-enter-from, .tag-list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
.tag-list-leave-active {
  position: absolute;
}

@keyframes bx-fade-in-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bx-tag-input {
    width: 100%;
  }
}
</style>

